#ifndef _BUOLA_MEDIA_CODEC_BFFMPEGENCODER_H_
#define _BUOLA_MEDIA_CODEC_BFFMPEGENCODER_H_

#include <buola/bbox/bservice.h>

#include <buola/bbox/bdatain.h>
#include <buola/bbox/bstreamin.h>
#include <buola/bbox/bstreamout.h>

#include <buola/image/format.h>

namespace buola { namespace media {

namespace ffmpeg {

    class COutputContext;
    class COutputAudioStream;
    class COutputVideoStream;
    
/*namespace ffmpeg*/ }
    
class BFfmpegEncoder : public bbox::BService<BFfmpegEncoder>
{
    struct SAudio
    {
        std::string mCodec;
        
        bbox::BStreamIn<int16_t> *iAudio;
        
        std::unique_ptr<ffmpeg::COutputAudioStream> mStream;
    };
    
    struct SVideo
    {
        std::string mCodec;
        CSize_i mSize;
        
        bbox::BDataIn<img::CImage_rgb8> *iVideo;
        
        std::unique_ptr<ffmpeg::COutputVideoStream> mStream;
    };

public:
    BFfmpegEncoder();
    ~BFfmpegEncoder();

    void SetFormat(const std::string &pFormat);
    
    void AddAudioStream(const std::string &pCodec);
    void AddVideoStream(const std::string &pCodec,const CSize_i &pSize);
    
private:
    void ClockCB(int i);
    
    virtual void DoInitialize();
    virtual void DoActivate();

private:
    std::unique_ptr<ffmpeg::COutputContext> mCtx;
    std::vector<std::unique_ptr<SAudio>> mAudio;
    std::vector<std::unique_ptr<SVideo>> mVideo;
    std::string mFormat;

public:
    std::vector<bbox::BStreamIn<int16_t>*> iAudio;
    std::vector<bbox::BDataIn<img::CImage_rgb8>*> iVideo;
    bbox::BStreamOut<uint8_t> oData;
};

/*namespace media*/ } /*namespace buola*/ }

#endif
